package my.concurrent;

import util.MathUtil;

//不安全的取钱
//两个人去银行取钱，同一个账户
public class UnsafeBank {
    public static void main(String[] args) {
        // 线程不安全的原因是一个对象要被多个线程使用，又因为各个线程的操作不是原子操作，所以互相干扰了

        Account account = new Account(100,"私房钱");

        Bank you = new Bank(account,50,"你");
        Bank girlfriend = new Bank(account,100,"女朋友");
        you.start();
        girlfriend.start();

        /* 其中一个结果：
            私房钱余额为-50
            私房钱余额为-50
            你手里的钱为50
            女朋友手里的钱为100
            因为逻辑里有判断，如果钱不够是无法取钱的，所以这里出现了余额为负数，说明出现了线程安全问题，原因就在于操作不是原子操作。
            两个线程的判断都通过了，这是因为“你”判断余额后还没有进行减余额的操作“女朋友”线程就开始判断了，结果使得判断通过了
        */

    }
}

//账户
class Account{
    int money;
    String name;

    public Account(int money,String name) {
        this.money = money;//账户里的钱
        this.name = name;//账户名字
    }
}

//银行

class Bank extends Thread{
    Account account;//账户

    int getMoney;//取走的钱

    int nowMoney;//记录现在手里的钱

    public Bank(Account account,int getMoney,String name) {
        super(name);
        this.account = account;
        this.getMoney = getMoney;
    }
    //取钱
    @Override
    public void run() {
        //判断账户里还有没有钱
        if (account.money - getMoney < 0){
            System.out.println(Thread.currentThread().getName()+ "要取钱但是钱不够了");
            return;
        }

        MathUtil.resolvePrime10();
        //账户余额 = 账户余额 - 你取走的钱
        account.money = account.money - getMoney;
        //现在手里的钱  = 现在手里的钱 + 取走的钱
        nowMoney = nowMoney + getMoney;

        System.out.println(account.name + "余额为" + account.money);
        System.out.println(Thread.currentThread().getName() + "手里的钱为" + nowMoney);
    }
}
